<template>
  <div
    class="bg"
    :style="{
      background: bgColor,
      width: skeleton.width + 'px',
      height: skeleton.height + 'px',
      left: skeleton.left + 'px',
      top: skeleton.top + 'px',
    }"
  >
    <!-- 矩形 -->
    <div
      v-for="(el, i) in skeletonRectLists"
      :key="i"
      class="skeleton-rect"
      :style="{
        width: el.offsetWidth + 'px',
        height: el.offsetHeight + 'px',
        left: el.getBoundingClientRect().left + 'px',
        top: el.getBoundingClientRect().top + 'px',
      }"
    ></div>
    <!-- 圆形 -->
    <div
      v-for="(el, i) in skeletonCircleLists"
      :key="i + 1000"
      class="skeleton-circle"
      :style="{
        width: el.offsetWidth + 'px',
        height: el.offsetHeight + 'px',
        left: el.getBoundingClientRect().left + 'px',
        top: el.getBoundingClientRect().top + 'px',
      }"
    ></div>
  </div>
</template>

<script>
export default {
  name: "my-skeleton",
  props: {
    bgColor: {
      type: String,
      default: "#fff",
    },
  },
  data() {
    return {
      skeleton: {
        width: "100%",
        height: "100%",
        left: 0,
        top: 0,
      },
      skeletonRectLists: [],
      skeletonCircleLists: [],
    };
  },
  mounted() {
    this.init();
    Promise.all([
      this.getNodes(".skeleton-rect"),
      this.getNodes(".skeleton-radius"),
    ]).then((res) => {
      this.skeletonRectLists = res[0];
      this.skeletonCircleLists = res[1];
    });
  },
  methods: {
    init() {
      const skeleton = document.querySelector(".skeleton");
      this.skeleton.height = skeleton.offsetHeight;
      this.skeleton.width = skeleton.offsetWidth;
      this.skeleton.top = skeleton.getBoundingClientRect().top;
      this.skeleton.left = skeleton.getBoundingClientRect().left;
    },
    getNodes(selector) {
      return new Promise((resolve) => {
        const skeleton = document.querySelector(".skeleton");
        const domNode = skeleton.querySelectorAll(selector);
        resolve(domNode);
      });
    },
  },
};
</script>

<style scoped lang="less">
/* 背景 */
.bg {
  background: #fff;
  position: fixed;
  z-index: 100;
  overflow: hidden;
}

/* 样式 */
.skeleton-rect {
  position: fixed;
  background: rgb(194, 207, 214);
  animation: blink 2s infinite;
  border-radius: 4px;
  padding: 2px;
  z-index: 10;
}

.skeleton-circle {
  position: fixed;
  background: rgb(194, 207, 214);
  animation: blink 2s infinite;
  border-radius: 100%;
  padding: 2px;
  z-index: 10;
}

/* 字体动画 */
@keyframes blink {
  0% {
    opacity: 0.8;
  }
  50% {
    opacity: 1;
  }
  100% {
    opacity: 0.8;
  }
}
</style>
